package com.warmheart.base.config;

import java.io.ByteArrayOutputStream;
import java.io.DataInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.MalformedURLException;
import java.net.URL;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

import org.apache.commons.net.ftp.FTP;
import org.apache.commons.net.ftp.FTPClient;
import org.apache.commons.net.ftp.FTPReply;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.multipart.MultipartFile;

import com.warmheart.core.util.UUIDGenerator;
import com.warmheart.core.util.cache.ConfigCacheService;

/**
 * 
 * @ClassName: WhFileUploadService
 * @Description: 文件上传服务
 * @author ZhangJianyang
 * @date 2025-06-16 09:37:02
 *
 */
public abstract class WhFileUploadService implements IWhConfigService<WhUploadConfig> {

    @Autowired(required = false)
    private ConfigCacheService configCacheService;

    /**
     * 上传File文件
     * 
     * @param temp
     * @param suffix
     * @return
     * @throws Exception
     */
    public String uploadFile(File temp, String suffix) throws Exception {
        FTPClient ftp = null;
        String netPath = null;
        try {
            String newFileName = UUIDGenerator.getUUID() + "." + suffix;
            Date currDate = new Date();

            netPath = "/" + new SimpleDateFormat("yyyy/MM/dd").format(currDate) + "/" + newFileName;

            // 这里判断FTP服务器所在系统类型进行区分
            String separatorStr = File.separator;
            if (config().getSystemType().equals("LINUX")) {
                separatorStr = "/";
            } else {
                separatorStr = "\\";
            }
            String filePath = new SimpleDateFormat("yyyy" + separatorStr + "MM" + separatorStr + "dd").format(currDate);
            ftp = new FTPClient();
            ftp.setControlEncoding("utf-8");

            int reply;
            ftp.connect(config().getBaseUrl(), Integer.parseInt(config().getFtpPort()));// 连接FTP服务器
            // 如果采用默认端口，可以使用ftp.connect(host)的方式直接连接FTP服务器
            ftp.login(config().getUserName(), config().getPassWord());// 登录
            reply = ftp.getReplyCode();
            if (!FTPReply.isPositiveCompletion(reply)) {
                ftp.disconnect();
                return null;
            }
            String basePath = config().getHomeDir() + separatorStr + config().getCommonPath();
            // 切换到上传目录
            if (!ftp.changeWorkingDirectory(basePath + separatorStr + filePath)) {
                // 如果目录不存在创建目录
                String[] dirs = filePath.split(separatorStr);
                String tempPath = basePath;
                if (!ftp.changeWorkingDirectory(tempPath)) {
                    if (!ftp.makeDirectory(tempPath)) {
                        return null;
                    } else {
                        ftp.changeWorkingDirectory(tempPath);
                    }
                }
                for (String dir : dirs) {
                    if (null == dir || "".equals(dir))
                        continue;
                    tempPath += separatorStr + dir;
                    if (!ftp.changeWorkingDirectory(tempPath)) {
                        if (!ftp.makeDirectory(tempPath)) {
                            return null;
                        } else {
                            ftp.changeWorkingDirectory(tempPath);
                        }
                    }
                }
            }
            // 准备传输数据，做出如下设置
            // 设置上传文件的类型为二进制类型
            ftp.setFileType(FTP.BINARY_FILE_TYPE);
            // 设置被动模式
            ftp.enterLocalPassiveMode();
            FileInputStream input = new FileInputStream(temp);

            // 上传文件
            if (!ftp.storeFile(newFileName, input)) {
                return null;
            }
            input.close();
            ftp.logout();
        } catch (IOException e) {
            e.printStackTrace();
            return null;
        } finally {
            // 如果FTP连接已经建立并且没有断开，则断开连接
            if (ftp != null && ftp.isConnected()) {
                try {
                    ftp.disconnect();
                } catch (IOException ioe) {
                }
            }
            // 删除临时文件
            if (temp != null) {
                temp.delete();
            }
        }
        return netPath;
    }

    public String uploadFile(MultipartFile mfile) throws Exception {
        String typePath = config().getImagePath();
        String fileType = mfile.getContentType();
        if (!fileType.startsWith("image/")) {
            typePath = config().getCommonPath();
        }
        FTPClient ftp = null;
        String netPath = null;
        try {
            // 文件名后缀
            String suffix = mfile.getOriginalFilename().substring(mfile.getOriginalFilename().lastIndexOf("."));

            String newFileName = UUIDGenerator.getUUID() + suffix;
            Date currDate = new Date();

            netPath = "/" + new SimpleDateFormat("yyyy/MM/dd").format(currDate) + "/" + newFileName;

            // 这里判断FTP服务器所在系统类型进行区分
            String separatorStr = File.separator;
            if (config().getSystemType().equals("LINUX")) {
                separatorStr = "/";
            } else {
                separatorStr = "\\";
            }
            String filePath = new SimpleDateFormat("yyyy" + separatorStr + "MM" + separatorStr + "dd").format(currDate);
            ftp = new FTPClient();
            ftp.setControlEncoding("utf-8");

            int reply;
            ftp.connect(config().getBaseUrl(), Integer.parseInt(config().getFtpPort()));// 连接FTP服务器
            // 如果采用默认端口，可以使用ftp.connect(host)的方式直接连接FTP服务器
            ftp.login(config().getUserName(), config().getPassWord());// 登录
            reply = ftp.getReplyCode();
            if (!FTPReply.isPositiveCompletion(reply)) {
                ftp.disconnect();
                return null;
            }
            String basePath = config().getHomeDir() + separatorStr + typePath;
            // 切换到上传目录
            if (!ftp.changeWorkingDirectory(basePath + separatorStr + filePath)) {
                // 如果目录不存在创建目录
                String[] dirs = filePath.split(separatorStr);
                String tempPath = basePath;
                if (!ftp.changeWorkingDirectory(tempPath)) {
                    if (!ftp.makeDirectory(tempPath)) {
                        return null;
                    } else {
                        ftp.changeWorkingDirectory(tempPath);
                    }
                }
                for (String dir : dirs) {
                    if (null == dir || "".equals(dir))
                        continue;
                    tempPath += separatorStr + dir;
                    if (!ftp.changeWorkingDirectory(tempPath)) {
                        if (!ftp.makeDirectory(tempPath)) {
                            return null;
                        } else {
                            ftp.changeWorkingDirectory(tempPath);
                        }
                    }
                }
            }
            // 准备传输数据，做出如下设置
            // 设置上传文件的类型为二进制类型
            ftp.setFileType(FTP.BINARY_FILE_TYPE);
            // 设置被动模式
            ftp.enterLocalPassiveMode();
            InputStream input = mfile.getInputStream();

            // 上传文件
            if (!ftp.storeFile(newFileName, input)) {
                return null;
            }
            input.close();
            ftp.logout();
        } catch (IOException e) {
            e.printStackTrace();
            return null;
        } finally {
            // 如果FTP连接已经建立并且没有断开，则断开连接
            if (ftp != null && ftp.isConnected()) {
                try {
                    ftp.disconnect();
                } catch (IOException ioe) {
                }
            }
        }
        return netPath;
    }

    public String uploadApp(MultipartFile mfile) throws Exception {
        FTPClient ftp = null;
        String netPath = null;
        try {
            // 文件名后缀
            String suffix = mfile.getOriginalFilename().substring(mfile.getOriginalFilename().lastIndexOf("."));

            String newFileName = UUIDGenerator.getUUID() + suffix;
            Date currDate = new Date();

            netPath = "/" + new SimpleDateFormat("yyyy/MM/dd").format(currDate) + "/" + newFileName;

            // 这里判断FTP服务器所在系统类型进行区分
            String separatorStr = File.separator;
            if (config().getSystemType().equals("LINUX")) {
                separatorStr = "/";
            } else {
                separatorStr = "\\";
            }
            String filePath = new SimpleDateFormat("yyyy" + separatorStr + "MM" + separatorStr + "dd").format(currDate);
            ftp = new FTPClient();
            ftp.setControlEncoding("utf-8");

            int reply;
            ftp.connect(config().getBaseUrl(), Integer.parseInt(config().getFtpPort()));// 连接FTP服务器
            // 如果采用默认端口，可以使用ftp.connect(host)的方式直接连接FTP服务器
            ftp.login(config().getUserName(), config().getPassWord());// 登录
            reply = ftp.getReplyCode();
            if (!FTPReply.isPositiveCompletion(reply)) {
                ftp.disconnect();
                return null;
            }
            String basePath = config().getHomeDir() + separatorStr + config().getAppPath();
            // 切换到上传目录
            if (!ftp.changeWorkingDirectory(basePath + separatorStr + filePath)) {
                // 如果目录不存在创建目录
                String[] dirs = filePath.split(separatorStr);
                String tempPath = basePath;
                if (!ftp.changeWorkingDirectory(tempPath)) {
                    if (!ftp.makeDirectory(tempPath)) {
                        return null;
                    } else {
                        ftp.changeWorkingDirectory(tempPath);
                    }
                }
                for (String dir : dirs) {
                    if (null == dir || "".equals(dir))
                        continue;
                    tempPath += separatorStr + dir;
                    if (!ftp.changeWorkingDirectory(tempPath)) {
                        if (!ftp.makeDirectory(tempPath)) {
                            return null;
                        } else {
                            ftp.changeWorkingDirectory(tempPath);
                        }
                    }
                }
            }
            // 准备传输数据，做出如下设置
            // 设置上传文件的类型为二进制类型
            ftp.setFileType(FTP.BINARY_FILE_TYPE);
            // 设置被动模式
            ftp.enterLocalPassiveMode();
            InputStream input = mfile.getInputStream();

            // 上传文件
            if (!ftp.storeFile(newFileName, input)) {
                return null;
            }
            input.close();
            ftp.logout();
        } catch (IOException e) {
            e.printStackTrace();
            return null;
        } finally {
            // 如果FTP连接已经建立并且没有断开，则断开连接
            if (ftp != null && ftp.isConnected()) {
                try {
                    ftp.disconnect();
                } catch (IOException ioe) {
                }
            }
        }
        return netPath;
    }

    public Map<String, String> uploadCommonSelf(MultipartFile mfile) {
        String typePath = config().getImagePath();
        String fileType = mfile.getContentType();
        if (!fileType.startsWith("image/")) {
            typePath = config().getCommonPath();
        }
        InputStream inputStream = null;
        OutputStream os = null;
        try {
            inputStream = mfile.getInputStream();

            Date currDate = new Date();
            String path = config().getHomeDir() + File.separator + typePath + File.separator
                    + new SimpleDateFormat("yyyyMMdd").format(currDate);
            // 2、保存到临时文件
            // 1K的数据缓冲
            byte[] bs = new byte[1024];
            // 读取到的数据长度
            int len;
            // 输出的文件流保存到本地文件

            File tempFile = new File(path);
            if (!tempFile.exists()) {
                tempFile.mkdirs();
            }

            String prefix = UUIDGenerator.getUUID();
            String suffix = mfile.getOriginalFilename().substring(mfile.getOriginalFilename().lastIndexOf("."));
            os = new FileOutputStream(path + File.separator + prefix + suffix);
            // 开始读取
            while ((len = inputStream.read(bs)) != -1) {
                os.write(bs, 0, len);
            }

            String netPath = null;

            netPath = "/" + typePath + "/" + new SimpleDateFormat("yyyyMMdd").format(currDate) + "/" + prefix + suffix;
            Map<String, String> resultMap = new HashMap<String, String>();
            resultMap.put("netPath", netPath);
            resultMap.put("netUrl", config().getDomainUrl() + netPath);
            return resultMap;
        } catch (IOException e) {
            e.printStackTrace();
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            // 完毕，关闭所有链接
            try {
                os.close();
                inputStream.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        return null;
    }

    public String uploadFileSelf(MultipartFile mfile) {
        String typePath = config().getImagePath();
        String fileType = mfile.getContentType();
        if (!fileType.startsWith("image/")) {
            typePath = config().getCommonPath();
        }

        InputStream inputStream = null;
        OutputStream os = null;
        try {
            inputStream = mfile.getInputStream();
            String path = config().getHomeDir() + "/" + typePath;
            // 2、保存到临时文件
            // 1K的数据缓冲
            byte[] bs = new byte[1024];
            // 读取到的数据长度
            int len;
            // 输出的文件流保存到本地文件

            File tempFile = new File(path);
            if (!tempFile.exists()) {
                tempFile.mkdirs();
            }

            String fileName = path + File.separator + mfile.getOriginalFilename();
            File oldFile = new File(fileName);
            if (oldFile.exists()) {
                oldFile.delete();
            }

            os = new FileOutputStream(fileName);
            // 开始读取
            while ((len = inputStream.read(bs)) != -1) {
                os.write(bs, 0, len);
            }

            String netPath = null;
            netPath = fileName;
            return netPath;
        } catch (IOException e) {
            e.printStackTrace();
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            // 完毕，关闭所有链接
            try {
                os.close();
                inputStream.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        return null;
    }

    public Map<String, String> uploadVideoSelf(MultipartFile mfile) {
        Map<String, String> uploadResultMap = new HashMap<String, String>();

        InputStream inputStream = null;
        OutputStream os = null;
        try {
            inputStream = mfile.getInputStream();

            Date currDate = new Date();
            String path = config().getHomeDir() + "/" + config().getVideoPath() + "/"
                    + new SimpleDateFormat("yyyyMMdd").format(currDate);
            // 2、保存到临时文件
            // 1K的数据缓冲
            byte[] bs = new byte[1024];
            // 读取到的数据长度
            int len;
            // 输出的文件流保存到本地文件

            File tempFile = new File(path);
            if (!tempFile.exists()) {
                tempFile.mkdirs();
            }

            String prefix = UUIDGenerator.getUUID();
            String suffix = mfile.getOriginalFilename().substring(mfile.getOriginalFilename().lastIndexOf("."));
            os = new FileOutputStream(path + File.separator + prefix + suffix);
            // 开始读取
            while ((len = inputStream.read(bs)) != -1) {
                os.write(bs, 0, len);
            }
            String netPath = null;
            netPath = "/" + new SimpleDateFormat("yyyyMMdd").format(currDate) + "/" + prefix + suffix;

            String filePrefix = configCacheService.getFilePrefix();
            uploadResultMap.put("netUrl", filePrefix + netPath);
            uploadResultMap.put("filePath", netPath);
        } catch (IOException e) {
            e.printStackTrace();
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            // 完毕，关闭所有链接
            try {
                os.close();
                inputStream.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        return uploadResultMap;
    }

    public String uploadAppSelf(MultipartFile mfile) {
        InputStream inputStream = null;
        OutputStream os = null;
        try {
            inputStream = mfile.getInputStream();

            Date currDate = new Date();
            String path = config().getHomeDir() + "/" + config().getAppPath() + "/"
                    + new SimpleDateFormat("yyyyMMdd").format(currDate);
            // 2、保存到临时文件
            // 1K的数据缓冲
            byte[] bs = new byte[1024];
            // 读取到的数据长度
            int len;
            // 输出的文件流保存到本地文件

            File tempFile = new File(path);
            if (!tempFile.exists()) {
                tempFile.mkdirs();
            }

            String prefix = UUIDGenerator.getUUID();
            String suffix = mfile.getOriginalFilename().substring(mfile.getOriginalFilename().lastIndexOf("."));
            os = new FileOutputStream(path + File.separator + prefix + suffix);
            // 开始读取
            while ((len = inputStream.read(bs)) != -1) {
                os.write(bs, 0, len);
            }

            String netPath = null;

            netPath = "/" + config().getAppPath() + "/" + new SimpleDateFormat("yyyyMMdd").format(currDate) + "/"
                    + prefix + suffix;

            return netPath;
        } catch (IOException e) {
            e.printStackTrace();
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            // 完毕，关闭所有链接
            try {
                os.close();
                inputStream.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        return null;
    }

    public String downloadPicture(String picUrl) {
        URL url = null;
        // int imageNumber = 0;

        try {
            url = new URL(picUrl);
            DataInputStream dataInputStream = new DataInputStream(url.openStream());

            Date currDate = new Date();
            String path = config().getDownloadDir() + "/" + config().getDownloadPath() + "/"
                    + new SimpleDateFormat("yyyyMMdd").format(currDate);

            File tempFile = new File(path);
            if (!tempFile.exists()) {
                tempFile.mkdirs();
            }

            String prefix = UUIDGenerator.getUUID();
            String suffix = ".png";
            String imageName = path + "/" + prefix + suffix;

            File originalFile = new File(imageName);
            FileOutputStream fileOutputStream = new FileOutputStream(originalFile);
            ByteArrayOutputStream output = new ByteArrayOutputStream();

            byte[] buffer = new byte[1024];
            int length;

            while ((length = dataInputStream.read(buffer)) > 0) {
                output.write(buffer, 0, length);
            }
            fileOutputStream.write(output.toByteArray());
            dataInputStream.close();
            fileOutputStream.close();

            String netPath = null;
            netPath = "/" + config().getDownloadPath() + "/" + new SimpleDateFormat("yyyyMMdd").format(currDate) + "/"
                    + prefix + suffix;

            return netPath;
        } catch (MalformedURLException e) {
            e.printStackTrace();
            return "";
        } catch (IOException e) {
            e.printStackTrace();
            return "";
        }
    }

    public OutputStream createImageOs(String imageName) {
        String typePath = config().getCodePath();

        OutputStream os = null;
        try {
            Date currDate = new Date();
            String path = config().getHomeDir() + "/" + typePath + "/"
                    + new SimpleDateFormat("yyyyMMdd").format(currDate);
            File tempFile = new File(path);
            if (!tempFile.exists()) {
                tempFile.mkdirs();
            }

            String suffix = ".jpg";
            os = new FileOutputStream(path + File.separator + imageName + suffix);
            return os;
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
        }
        return null;
    }

    public void removeFileSelf(String url) {
        try {
            String path = config().getHomeDir() + url;
            File tempFile = new File(path);
            if (tempFile.exists()) {
                tempFile.delete();
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
        }
    }
}
